#include "talloc.h"
#include "xenstored_core.h"
#include "xenstored_domain.h"
+#include "xenstored_transaction.h"
#include "xenstored_watch.h"
#include "xenstored_test.h"
return NULL;
}
+static void domain_conn_reset(struct domain *domain)
+{
+ struct connection *conn = domain->conn;
+ struct buffered_data *out;
+
+ conn_delete_all_watches(conn);
+ conn_delete_all_transactions(conn);
+
+ while ((out = list_top(&conn->out_list, struct buffered_data, list))) {
+ list_del(&out->list);
+ talloc_free(out);
+ }
+
+ talloc_free(conn->in->buffer);
+ memset(conn->in, 0, sizeof(*conn->in));
+ conn->in->inhdr = true;
+
+ domain->interface->req_cons = domain->interface->req_prod = 0;
+ domain->interface->rsp_cons = domain->interface->rsp_prod = 0;
+}
/* domid, mfn, evtchn, path */
void do_introduce(struct connection *conn, struct buffered_data *in)
talloc_steal(domain->conn, domain);
fire_watches(conn, "@introduceDomain", false);
- } else if (domain->mfn == mfn) {
+ } else if ((domain->mfn == mfn) && (domain->conn != conn)) {
/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
if (domain->port)
xc_evtchn_unbind(xce_handle, domain->port);
return;
}
- /* Rings must be quiesced. */
- domain->interface->req_cons = domain->interface->req_prod = 0;
- domain->interface->rsp_cons = domain->interface->rsp_prod = 0;
+ domain_conn_reset(domain);
send_ack(conn, XS_INTRODUCE);
}
#include <sys/wait.h>
#include <sys/time.h>
#include <time.h>
+#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include <fcntl.h>
send_ack(conn, XS_TRANSACTION_END);
}
+void conn_delete_all_transactions(struct connection *conn)
+{
+ struct transaction *trans;
+
+ while ((trans = list_top(&conn->transaction_list,
+ struct transaction, list))) {
+ list_del(&trans->list);
+ talloc_free(trans);
+ }
+
+ assert(conn->transaction == NULL);
+
+ conn->transaction_started = 0;
+}
+
/*
* Local variables:
* c-file-style: "linux"
send_error(conn, ENOENT);
}
+void conn_delete_all_watches(struct connection *conn)
+{
+ struct watch *watch;
+
+ while ((watch = list_top(&conn->watches, struct watch, list))) {
+ list_del(&watch->list);
+ talloc_free(watch);
+ domain_watch_dec(conn);
+ }
+}
+
#ifdef TESTING
void dump_watches(struct connection *conn)
{